//
//  FilterViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 8/1/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit
import SnapKit

final class FilterViewController: UIViewController, Alertable {
    
    // MARK: - Outlet
    
    private lazy var modalView: ModalView = {
        let mView = ModalView()
        mView.delegate = self
        return mView
    }()
    
    private lazy var tableView: UITableView = {
        let tableView = UITableView()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(GeneralCell.self, forCellReuseIdentifier: "GeneralCell")
        tableView.register(FilterCarCell.self, forCellReuseIdentifier: "FilterCarCell")
        tableView.register(FilterOptionalCell.self, forCellReuseIdentifier: "FilterOptionalCell")
        tableView.register(FilterChecksCell.self, forCellReuseIdentifier: "FilterChecksCell")
        tableView.showsVerticalScrollIndicator = false
        tableView.backgroundColor = .whiteBlueColor
        tableView.separatorStyle = .none
        return tableView
    }()
    
    // MARK: - Props
    
    private var filterViewModel: FilterViewModel!
    var filter: Filter!
    var resultVC: ResultsViewController!
    private var lastRowIndex: Int?
    private var cells: [UITableViewCell] = []
    
    // MARK: - Action
    
    @objc private func onReady (sender: UIButton) {
        self.getCellData()
    }
    
    @objc private func goBack (sender: Any) {
        self.navigationController?.popViewController(animated: true)
    }
    
    @objc private func onReset (sender: Any) {
        self.filter = Filter(filterGeneral: Filter.FilterGeneral(),
                             filterCar: Filter.FilterCar(),
                             filterOptional: Filter.FilterOptional(),
                             filterChecks: Filter.FilterChecks(),
                             carDetailedType: nil)
        tableView.reloadSections(IndexSet(arrayLiteral: 0), with: .top)
        tableView.reloadData()
    }
    
    // MARK: - Init
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.addView()
        self.setUpNavBar()
        filterViewModel = FilterViewModel(filter: filter)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        NotificationCenter.default.addObserver(self, selector: #selector(openModal(notification:)), name: NSNotification.Name(rawValue: "openModal"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(openOptions(notification:)), name: NSNotification.Name(rawValue: "openOptions"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleCell(notification:)), name: NSNotification.Name(rawValue: "handleCell"), object: nil)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "openModal"), object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "openOptions"), object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "handleCell"), object: nil)
    }
}

// MARK: - Methods

extension FilterViewController {
    
    /// Open Modal for (Мощность, Цвет, Привод)
    /// - Parameter notification: Notification that contains *marka*
    @objc private func openModal (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            let modal = userInfo["modal"] as! ModalView.ModalType
            self.addModalView(modalType: modal)
        }
    }
    
    /// on *Выбрать опции* button click
    /// - Parameter notification: contains nothing
    @objc private func openOptions (notification: NSNotification) {
        let optionsVC = OptionsViewController()
        optionsVC.updateSelectedItemsAfterFetch = true
        optionsVC.filterOptions = [
            filter.filterOptional.options_single_fields ?? "",
            filter.filterOptional.options_choice_fields ?? "",
            filter.filterOptional.options_multiple_fields ?? ""
        ]
        optionsVC.callbackVC = self
        self.navigationController?.pushViewController(optionsVC, animated: true)
    }
    
    /// General function that was sent from cell
    /// - Parameter notification: NSNotification, that contains info about *cell*
    @objc private func handleCell (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            if !(userInfo["isClick"] as? Bool ?? true) {
                tableView.beginUpdates()
                tableView.endUpdates()
            } else if (userInfo["cell"] as! UITableViewCell) is FilterCarCell {
                self.selectCarMarkModel(userInfo: userInfo)
            } else if (userInfo["cell"] as! UITableViewCell) is GeneralCell {
                if userInfo["type"] as! String == "region" {
                    self.selectRegion()
                }
            }
        }
    }

    /// Collecting all data into one struct
    private func getCellData () {
        for (i, item) in filterViewModel.items.enumerated() {
            let cell = cells[i]
            let data = item.returnData(cell: cell)
            if (data is Filter.FilterGeneral) {
                filter.filterGeneral = data as! Filter.FilterGeneral
            } else if data is Filter.FilterCar {
                filter.filterCar = data as! Filter.FilterCar
            } else if data is Filter.FilterChecks {
                filter.filterChecks = data as! Filter.FilterChecks
            } else if data is Filter.FilterOptional {
                let sfOptions = filter.filterOptional.options_single_fields
                let cfOptions = filter.filterOptional.options_choice_fields
                let mfOptions = filter.filterOptional.options_multiple_fields
                filter.filterOptional = data as! Filter.FilterOptional
                filter.filterOptional.options_single_fields = sfOptions
                filter.filterOptional.options_choice_fields = cfOptions
                filter.filterOptional.options_multiple_fields = mfOptions
            }
        }
        
        if resultVC == nil {
            resultVC = ResultsViewController()
            resultVC.addFilter(filter: self.filter)
            self.navigationController?.pushViewController(resultVC, animated: true)
        } else {
            resultVC.addFilter(filter: self.filter)
            self.navigationController?.popViewController(animated: true)
        }
    }
    
    /// Moving to Marka or Model View Controller
    /// - Parameter userInfo: Contains info about *item*, *index*
    private func selectCarMarkModel (userInfo: [AnyHashable: Any]) {
        let item = userInfo["item"] as! ParametersViewModel?
        self.lastRowIndex = userInfo["index"] as? Int
        
        if (item?.type == "marka") {
            let vc = MarksViewController()
            vc.setProps(carData: CarData(), resultDelegate: self)
            self.navigationController?.pushViewController(vc, animated: true)
        } else if item?.type == "model" {
            let vc = ModelsViewController()
            let marka = userInfo["marka"] as! Marka
            vc.setProps(carData: CarData(marka: marka), resultDelegate: self)
            self.navigationController?.pushViewController(vc, animated: true)
        } else {
            let vc = GenerationViewController()
            vc.resultsVC = self
            vc.carData = CarData(marka: self.filter.filterCar.carParameters?.marka)
            let _models = userInfo["models"] as! [Model]

            vc.models = _models
            self.navigationController?.pushViewController(vc, animated: true)
        }
    }
    
    /// Moving to Region View Controller
    private func selectRegion () {
        let regionVC = RegionViewController()
        regionVC.delegate = self
        self.navigationController?.pushViewController(regionVC, animated: true)
    }
}


extension FilterViewController: OptionsViewControllerDelegate, RegionViewControllerDelegate {

    func selectCity(city: [City]) {
        filter.filterGeneral.region = city
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "setGeneral"), object: nil, userInfo: [
                "type": "region",
                "data": city
        ])
    }

    func didSelectedOptions(options: [String : Any]?, filterFormat: [String]?) {
        filter.filterOptional.options_single_fields = filterFormat![0]
        filter.filterOptional.options_choice_fields = filterFormat![1]
        filter.filterOptional.options_multiple_fields = filterFormat![2]
    }
}


extension FilterViewController {
    
    private func addView () {
        self.view.addSubview(tableView)
        tableView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
    }
    
    private func addModalView (modalType: ModalView.ModalType) {
        self.view.addSubview(modalView)
        modalView.updateModalType(type: modalType)
        
        let height = modalType == .price ? 240 : 345
        
        modalView.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
            make.height.equalTo(height)
        }
    }
    
    private func setUpNavBar() {
         self.navigationController?.navigationBar.isHidden = false
         self.navigationController?.navigationBar.defaultNavBar()
         let backIcon = UIImage(named: "cancel")
         let backButton = UIBarButtonItem(image: backIcon, landscapeImagePhone: backIcon, style: .plain, target: self, action: #selector(goBack(sender:)))
         backButton.tintColor = .greyColor
         let resetBtn = UIBarButtonItem(title: "Сбросить", style: .plain, target: self, action: #selector(onReset(sender:)))
         self.navigationItem.rightBarButtonItem = resetBtn
         self.navigationItem.simpleNavBar(title: "Параметры", backButton: backButton)
    }
}



extension FilterViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return filterViewModel.items.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = filterViewModel.items[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: type(of: item).reuseId)!
        cell.selectionStyle = .none
        item.configure(cell: cell, index: indexPath.row)
        cells.append(cell)
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let _view = UIView()
        _view.frame = CGRect(x: 0, y: 0, width: tableView.frame.width, height: 88)

        let btn = UIButton()
        btn.backgroundColor = .blueColor
        btn.clipsToBounds = true
        btn.layer.cornerRadius = 15

        btn.setTitle("Показать результаты", for: .normal)
        btn.setTitleColor(.white, for: .normal)
        btn.addTarget(self, action: #selector(onReady(sender:)), for: .touchUpInside)


        _view.addSubview(btn)
        btn.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalToSuperview().offset(-12)
            make.height.equalTo(44)
        }

        return _view
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 88
    }
}


extension FilterViewController: ModalViewDelegate {
    
    func onSubmit(for type: ModalView.ModalType, data: Any) {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "sendModal"), object: nil, userInfo: ["data": data, "type": type])
        modalView.removeFromSuperview()
        modalView.snp.removeConstraints()
    }
    
    func onCancel() {
        modalView.removeFromSuperview()
        modalView.snp.removeConstraints()
    }
    
    func showError(_ title: String, _ message: String) {
        self.showAlert(title, message)
    }
}

extension FilterViewController: ResultsVCDelegate {
    func goBack(data: CarFilter, type: MarkaModelMode) {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "putMarkModel"), object: nil, userInfo: [ "data": data, "type": type ])
        tableView.beginUpdates()
        tableView.endUpdates()
        lastRowIndex = nil
    }
}
